

import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.InputSource;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.xpath.XPathExpressionException;
import org.xml.sax.SAXException;

public class Routing {
	
  // URL prefix for routing
  private static final String ROUTING_REQUEST_PREFIX_FOR_XML = "http://maps.googleapis.com/maps/api/directions/xml";
  private static final String TRACT_REQUEST_PREFIX_FOR_XML="http://data.fcc.gov/api/block/2010/find";
static double[] lowerLat={43.177141,
	43.177141,
	43.177141,
	43.177141,
	43.056848,
	43.056848,
	43.056848,
	43.056848,
	42.956925,
	42.956925,
	42.956925,
	42.956925};
static double[] upperLat={43.275706,
	43.275706,
	43.275706,
	43.275706,
	43.177141,
	43.177141,
	43.177141,
	43.177141,
	43.056848,
	43.056848,
	43.056848,
	43.056848};
static double[] lowerLng={-77.871094,
	-77.724152,
	-77.565536,
	-77.400742,
	-77.871094,
	-77.724152,
	-77.565536,
	-77.400742,
	-77.871094,
	-77.724152,
	-77.565536,
	-77.400742};
static double[] upperLng={-77.724152,
	-77.565536,
	-77.400742,
	-77.268219,
	-77.724152,
	-77.565536,
	-77.400742,
	-77.268219,
	-77.724152,
	-77.565536,
	-77.400742,
	-77.268219};

  public static String getRoutesInfo(Map<String, Double> tractPowerDemandMap_endonly, Map<String, Double> tractPowerDemandMap, int routeIndex, String origin, String destination, boolean detailed) throws SAXException, IOException, ParserConfigurationException, XPathExpressionException{
	  	String routeInfo="";
	    URL url = new URL(ROUTING_REQUEST_PREFIX_FOR_XML + "?origin=" + URLEncoder.encode(origin, "UTF-8") + "&destination="+ URLEncoder.encode(destination, "UTF-8")+ "&sensor=false");
	    HttpURLConnection conn = (HttpURLConnection) url.openConnection();
	    Document routingResultDocument = null;
	    try {
	      // open the connection and get results as InputSource.
	      conn.connect();
	      InputSource routingResultInputSource = new InputSource(conn.getInputStream());
	      //printInputStream(conn.getInputStream());

	      // read result and parse into XML Document
	      routingResultDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(routingResultInputSource);
	    } finally {
	      conn.disconnect();
	    }

	    // prepare XPath
	    XPath xpath = XPathFactory.newInstance().newXPath();

	    // extract the result
		if(detailed){
			   // routeInfo+="Step\tTime(hr)\tDistance(km)\tStartLoc\t\tEndLoc\t\t\tCneeded\tChargeNeeded(Cumulative)\tTract\tTract11\n";
		}
	    if(!detailed) routeInfo+="Total,\t";
	    //total time and distance
	    NodeList totalDuration = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/duration/text", routingResultDocument, XPathConstants.NODESET);
	  //  for(int i=0; i<totalDuration.getLength(); ++i) {
	    	Double totalDurn=null;
	    	String totalDur = totalDuration.item(0).getTextContent();
	    	if(totalDur.contains("hours")){
	    		Pattern intsOnly = Pattern.compile("(\\d+) hours (\\d+)");
	    		Matcher match = intsOnly.matcher(totalDur);
	    		match.find();
	    		int hours= Integer.parseInt(match.group(1));
	    		int mins = Integer.parseInt(match.group(2));
	    		
	    		totalDurn = hours+mins/60.0;
	    	}else{
	    		totalDur=totalDur.replaceAll("[^.0-9]", "");
	    		totalDurn=Double.parseDouble(totalDur)/60.0;
	    	}
	    	 if(!detailed) routeInfo+=(String.format("% .3f", totalDurn)+",\t\t");

	 //   }
	    
	    NodeList totalDistance = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/distance/text", routingResultDocument, XPathConstants.NODESET);
	   // for(int i=0; i<totalDistance.getLength(); ++i) {
	    	Double totalDist=null;
	    	String totalDis = totalDistance.item(0).getTextContent();
	    	if(totalDis.contains("ft")){
	    		totalDis=totalDis.replaceAll("[^.0-9]", "");
	    		totalDist=(Double.parseDouble(totalDis)/5280.0)*1.60934;
	    	}else{
	    		totalDis=totalDis.replaceAll("[^.0-9]", "");
	    		totalDist=Double.parseDouble(totalDis)*1.60934;
	    	}
	    	 if(!detailed) routeInfo+=(String.format("%.3f", totalDist)+",\t\t");
	  //  }
	    
	    NodeList totalStartLat = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/start_location/lat", routingResultDocument, XPathConstants.NODESET);
	    for(int i=0; i<totalStartLat.getLength(); ++i) {
	    	 if(!detailed)routeInfo+=(totalStartLat.item(i).getTextContent()+",");
	    }
	    NodeList totalStartLng = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/start_location/lng", routingResultDocument, XPathConstants.NODESET);
	    for(int i=0; i<totalStartLng.getLength(); ++i) {
	    	 if(!detailed) routeInfo+=(totalStartLng.item(i).getTextContent()+",\t");
	    }
	    NodeList totalEndLat = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/end_location/lat", routingResultDocument, XPathConstants.NODESET);
	    for(int i=0; i<totalEndLat.getLength(); ++i) {
	    	 if(!detailed) routeInfo+=(totalEndLat.item(i).getTextContent()+",");
	    }
	    NodeList totalEndLng = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/end_location/lng", routingResultDocument, XPathConstants.NODESET);
	    for(int i=0; i<totalEndLng.getLength(); ++i) {
	    	 if(!detailed) routeInfo+=(totalEndLng.item(i).getTextContent()+",\t");
	    }
	    
	    double avgSpeed = totalDist/totalDurn;
	    double avgKw = .2766*avgSpeed-8.2207;
	    double totalKwh = avgKw*totalDurn;
	    
	    
	    
	    URL tractUrl = new URL(TRACT_REQUEST_PREFIX_FOR_XML + "?latitude=" + totalEndLat.item(0).getTextContent() + "&longitude="+ totalEndLng.item(0).getTextContent());
	    HttpURLConnection tractConn = (HttpURLConnection) tractUrl.openConnection();
	    Document tractDocument = null;
	    try {
	      // open the connection and get results as InputSource.
	    	tractConn.connect();
	      InputSource tractInputSource = new InputSource(tractConn.getInputStream());
	      //printInputStream(conn.getInputStream());

	      // read result and parse into XML Document
	      tractDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(tractInputSource);
	    } finally {
	    	tractConn.disconnect();
	    }
	    XPath tract_xpath = XPathFactory.newInstance().newXPath();
	    NodeList tract_nodes = (NodeList) tract_xpath.evaluate("/Response/Block/@FIPS", tractDocument, XPathConstants.NODESET);
	    String tract= String.format("%06d", Integer.parseInt(tract_nodes.item(0).getTextContent().substring(5, 11)));
	    String tract11=String.format("%06d", Long.parseLong(tract_nodes.item(0).getTextContent().substring(0, 11)));
//    	if(tractPowerDemandMap_endonly.containsKey(tract11)){
//    		tractPowerDemandMap_endonly.put(tract11, totalKwh+tractPowerDemandMap_endonly.get(tract11));
//    	}else{
//    		tractPowerDemandMap_endonly.put(tract11, totalKwh);
//    	}
    	
    	
    	
	    if(!detailed) routeInfo+= String.format("%.3f", totalKwh)+",\n";
	    if(detailed){
		    //individual steps
		    NodeList stepDuration = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/step/duration/text", routingResultDocument, XPathConstants.NODESET);
		    NodeList stepDistance = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/step/distance/text", routingResultDocument, XPathConstants.NODESET);
		    NodeList stepStartLat = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/step/start_location/lat", routingResultDocument, XPathConstants.NODESET);
		    NodeList stepStartLng = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/step/start_location/lng", routingResultDocument, XPathConstants.NODESET);
		    NodeList stepEndLat = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/step/end_location/lat", routingResultDocument, XPathConstants.NODESET);
		    NodeList stepEndLng = (NodeList) xpath.evaluate("/DirectionsResponse/route/leg/step/end_location/lng", routingResultDocument, XPathConstants.NODESET);
		    double cumKwh=0;
		    for(int i=0; i<stepDuration.getLength(); ++i) {
		    	
		    	Double dist=null;
		    	String dis = stepDistance.item(i).getTextContent();
		    	if(dis.contains("ft")){
		    		dis=dis.replaceAll("[^.0-9]", "");
		    		dist=(Double.parseDouble(dis)/5280.0)*1.60934;
		    	}else{
		    		dis=dis.replaceAll("[^.0-9]", "");
		    		dist=Double.parseDouble(dis)*1.60934;
		    	}
		    	Double durn=null;
		    	String dur = stepDuration.item(i).getTextContent();
		    	if(dur.contains("hours")){
		    		Pattern intsOnly = Pattern.compile("(\\d+) hours (\\d+)");
		    		Matcher match = intsOnly.matcher(dur);
		    		match.find();
		    		int hours= Integer.parseInt(match.group(1));
		    		int mins = Integer.parseInt(match.group(2));
		    		
		    		durn = hours+mins/60.0;
		    	}else{
		    		dur=dur.replaceAll("[^.0-9]", "");
		    		durn=Double.parseDouble(dur)/60.0;
		    	}
		      
		    	routeInfo+="Route"+routeIndex+",\t";
		    	routeInfo+="Step"+i+",\t";
		    	routeInfo+=(String.format("%2.3f", durn)+",\t");
		    	routeInfo+=(String.format("%2.3f", dist)+",\t\t");
		    	routeInfo+=(stepStartLat.item(i).getTextContent()+","+stepStartLng.item(i).getTextContent()+",\t\t");
		    	routeInfo+=(stepEndLat.item(i).getTextContent()+","+stepEndLng.item(i).getTextContent()+",\t");
		    	
			    double stepSpeed = dist/durn;
			    double stepKw;
			    if(stepSpeed>=40){
			    	stepKw= .2766*stepSpeed-8.2207;
			    }else{
			    	stepKw= .0625*stepSpeed+0.5;
			    }
			    double stepKwh = stepKw*durn;
			    cumKwh = cumKwh+stepKwh;
			    routeInfo+=String.format("%.3f", stepKwh)+",\t";
			    routeInfo+=String.format("%.3f", cumKwh)+",\t";
			    
			   
			    
			    tractUrl = new URL(TRACT_REQUEST_PREFIX_FOR_XML + "?latitude=" + stepEndLat.item(i).getTextContent() + "&longitude="+ stepEndLng.item(i).getTextContent());
			    tractConn = (HttpURLConnection) tractUrl.openConnection();
			    tractDocument = null;
			    try {
			      // open the connection and get results as InputSource.
			    	tractConn.connect();
			      InputSource tractInputSource = new InputSource(tractConn.getInputStream());
			      //printInputStream(conn.getInputStream());

			      // read result and parse into XML Document
			      tractDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(tractInputSource);
			    } finally {
			    	tractConn.disconnect();
			    }
			    tract_xpath = XPathFactory.newInstance().newXPath();
			    tract_nodes = (NodeList) tract_xpath.evaluate("/Response/Block/@FIPS", tractDocument, XPathConstants.NODESET);
			    tract= String.format("%06d", Integer.parseInt(tract_nodes.item(0).getTextContent().substring(5, 11)));
			    tract11=String.format("%06d", Long.parseLong(tract_nodes.item(0).getTextContent().substring(0, 11)));
		    	routeInfo+=tract+",\t"+tract11+"\n";
		    	if(tractPowerDemandMap.containsKey(tract11)){
		    		tractPowerDemandMap.put(tract11, stepKwh+tractPowerDemandMap.get(tract11));
		    	}else{
		    		tractPowerDemandMap.put(tract11, stepKwh);
		    	}
		    	
		    	if(i==stepDuration.getLength()-1){
			    	if(tractPowerDemandMap_endonly.containsKey(tract11)){
			    		tractPowerDemandMap_endonly.put(tract11, cumKwh+tractPowerDemandMap_endonly.get(tract11));
			    	}else{
			    		tractPowerDemandMap_endonly.put(tract11, cumKwh);
			    	}
		    	}

		    }
	    }

	    return routeInfo;

  }
  private static void printInputStream(InputStream inputStream) throws IOException {
      BufferedReader in = new BufferedReader(new InputStreamReader(inputStream));
      String inputLine;
      while ((inputLine = in.readLine()) != null)
          System.out.println(inputLine);
	
  }
  public static String getRandomValue(final Random random,
		    final double lowerBound,
		    final double upperBound,
		    final int decimalPlaces){

		    if( upperBound <= lowerBound || decimalPlaces < 0){
		        throw new IllegalArgumentException("Put error message here");
		    }

		    final double dbl =
		        ((random == null ? new Random() : random).nextDouble() //
		            * (upperBound - lowerBound))
		            + lowerBound;
		    return String.format("%." + decimalPlaces + "f", dbl);

		}
	public static final void main (String[] argv) throws IOException, XPathExpressionException, ParserConfigurationException, SAXException, InterruptedException {
	
		//generateUniformDistributionCoordinates(50);
		//generateDensityDistributionCoordinates(50);
		
		boolean detailed=true;
	    // query address
//	    String[] origin = {
//	    		"43.1097970,-77.6478563",
//	    		"43.2629207,-77.7575178",
//	    		"43.1154508,-77.5565895",
//	    		"43.0640487,-77.3133571",
//	    		"43.0272481,-77.5192875",
//	    		"43.1167131,-77.8544150",
//	    		"43.0619240,-77.7130433",
//	    		"43.1733888,-77.6181099",
//	    		"43.0527118,-77.5397141",
//	    		"43.2420325,-77.8701205",
//	    		"43.0862833,-77.6062699",
//	    		"42.9937975,-77.8615382",
//	    		"43.2636577,-77.7380495",
//	    		"43.0357318,-77.7304212",
//	    		"43.2178999,-77.8459478",
//	    		"43.2571598,-77.8003587",
//	    		"43.0616784,-77.8053175",
//	    		"43.0213690,-77.8316678",
//	    		"42.9894506,-77.5280640",
//	    		"43.0869011,-77.7748768",
//	    		"43.0249104,-77.7759651",
//	    		"43.1510130,-77.6512234",
//	    		"43.1652394,-77.3163570",
//	    		"43.1290005,-77.6303442",
//	    		"42.9638932,-77.7350483"};
//	    String[] destination = {
//	    		"43.2815780,-77.7181778",
//	    		"43.2315780,-77.7581778",
//	    		"43.2063734,-77.7921359",
//	    		"43.1600668,-77.3442189",
//	    		"43.2209429,-77.7556437",
//	    		"43.1518074,-77.6127994",
//	    		"43.2362013,-77.8323737",
//	    		"43.2730757,-77.8338832",
//	    		"43.0255747,-77.7370122",
//	    		"43.1872680,-77.7624752",
//	    		"43.2289200,-77.8423873",
//	    		"43.0993424,-77.7075828",
//	    		"43.1827260,-77.8262033",
//	    		"43.1003371,-77.5876962",
//	    		"43.1904558,-77.7280599",
//	    		"43.0907890,-77.7307025",
//	    		"43.2742827,-77.8514471",
//	    		"43.0824409,-77.4199380",
//	    		"43.2451757,-77.8468622",
//	    		"43.2261402,-77.8472476",
//	    		"43.1832341,-77.8615270",
//	    		"43.2731390,-77.7477670",
//	    		"43.1622015,-77.6157623",
//	    		"43.2534179,-77.7275414",
//	    		"43.0911259,-77.6473138"};
	    
		String prefix = "2000";
		String []origin = getLocationList(prefix+"sampleorigins.csv");
		String []destination = getLocationList(prefix+"sampledestinations.csv");
		  FileWriter fstream = new FileWriter(prefix+"routeInfo.csv");
		  BufferedWriter out = new BufferedWriter(fstream);
		  FileWriter tractPowerDemandStream = new FileWriter(prefix+"tractPowerDemand.csv");
		  BufferedWriter tractPowerDemand = new BufferedWriter(tractPowerDemandStream);
		Map<String,Double> tractPowerDemandMap = new HashMap<String,Double>();
		Map<String,Double> tractPowerDemandMap_endonly = new HashMap<String,Double>(); 
	   // generateJS(origin, destination);
	    if(!detailed){
	    	System.out.print("Step\tTime(hr)\tDistance(km)\tStartLoc\t\tEndLoc\t\t\tChargeNeeded\n");
	    }
	    out.write("Route,Step,Time,Distance,Start Lat, Start Lng, End Lat, End Lng, Step power, Cum Power,Tract6,Tract11\n");
	    for(int i =0; i<origin.length;i++){
	    	String output=getRoutesInfo(tractPowerDemandMap_endonly,tractPowerDemandMap,i,origin[i],destination[i],detailed);
	    	System.out.print(output);
	    	out.write(output);
	    	Thread.sleep(250);
	    }
	    //generateUniformDistributionCoordinatesWithTract(20000);
	    //readLocationsIntoTracts();
//	    generatePopulationDistributionCoordinates(8500,"8500sampledestination.csv");
	    tractPowerDemand.write("Tract11,Tract Power Depletition, Tract power depletion at end\n");
	    for(String key: tractPowerDemandMap.keySet()){
	    	
	    	Double d=tractPowerDemandMap_endonly.get(key);
	    	String temp="";
	    	if (d!=null){
	    		temp=d+"";
	    	}
	    	tractPowerDemand.write(key+","+tractPowerDemandMap.get(key)+","+temp+"\n");
	    	System.out.println(key+","+tractPowerDemandMap.get(key)+","+temp+"\n");
	    }
	    out.close();
	    tractPowerDemand.close();
	}
public static String[] getLocationList(String filename) throws IOException{
	ArrayList<ArrayList<String>> locationFile = CSVIO.readFile(filename);
	ArrayList<String> locationList = new ArrayList<String>();
	for(ArrayList<String> locationRow: locationFile){
		locationList.add(locationRow.get(2)+","+locationRow.get(3));
	}
	String []locationArray = new String[locationList.size()];
	for(int i =0; i<locationList.size();i++){
		locationArray[i]=locationList.get(i);
	}
	return locationArray;
}

public static void generateDensityDistributionCoordinates(int n){
    Double[] blockDensityDistribution = {0.4,0.4,0.4,0.4,0.5,0.6,0.7,0.8,0.9,0.930,0.970,1.0};
    
    for(int i =0; i<n; i++){
    	double densityPick = Double.parseDouble(getRandomValue(null,0,1,3));
    	
    	int blockIndex=-1;
    	for(int k=blockDensityDistribution.length-1; k>=0;k--){
    		if (densityPick<blockDensityDistribution[k]){
    			blockIndex=k;
    		}
    	}
    	if(blockIndex==-1){
    		System.err.println("Invalid distribution");	
    	}

		System.out.println("\""+getRandomValue(null, lowerLat[blockIndex], upperLat[blockIndex], 7)+","+getRandomValue(null, lowerLng[blockIndex], upperLng[blockIndex], 7)+"\",");
    	
    }
}
public static void generateUniformDistributionCoordinates(int n){
	//run on http://jsfiddle.net/bD6SH/
	for(int i=0;i<n;i++){
		System.out.println("\""+getRandomValue(null, 42.885021, 43.337165, 7)+","+getRandomValue(null, -77.976837, -77.277832, 7)+"\",");
	}
}

public static void generateUniformDistributionCoordinatesWithTract(int n) throws IOException, SAXException, ParserConfigurationException, XPathExpressionException{
	  FileWriter fstream = new FileWriter("out.csv");
	  BufferedWriter out = new BufferedWriter(fstream);
	for(int i=0;i<n;i++){
		String lat =getRandomValue(null, 42.885021, 43.337165, 7);
		String lng= getRandomValue(null, -77.976837, -77.277832, 7);
		
		  URL tractUrl = new URL(TRACT_REQUEST_PREFIX_FOR_XML + "?latitude=" + lat + "&longitude="+ lng);
		    HttpURLConnection tractConn = (HttpURLConnection) tractUrl.openConnection();
		    Document tractDocument = null;
		    try {
		      // open the connection and get results as InputSource.
		    	tractConn.connect();
		      InputSource tractInputSource = new InputSource(tractConn.getInputStream());
		      //printInputStream(conn.getInputStream());

		      // read result and parse into XML Document
		      tractDocument = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(tractInputSource);
		    } finally {
		    	tractConn.disconnect();
		    }
		    XPath tract_xpath = XPathFactory.newInstance().newXPath();
		    NodeList tract_nodes = (NodeList) tract_xpath.evaluate("/Response/Block/@FIPS", tractDocument, XPathConstants.NODESET);
		    String tract= String.format("%06d", Integer.parseInt(tract_nodes.item(0).getTextContent().substring(5, 11)));
		    String tract11= String.format("%011d", Long.parseLong(tract_nodes.item(0).getTextContent().substring(0, 11)));
	    	
		    if(i%10==0)System.out.println(i+": "+tract+", "+tract11+", "+ lat+", "+lng);
		    out.write(tract+", "+tract11+", "+ lat+", "+lng+"\n");
	}
	out.close();
	
}
public static void generateJS(String origin[], String destin[]){
	String js="";
	for(int i = 0; i< origin.length;i++){
	    js+="var origin"+i+" = new google.maps.LatLng("+origin[i]+");\n";
	    js+="var destin"+i+" = new google.maps.LatLng("+destin[i]+");\n";
	}

	
    js+="var map;\n";
    js+="var mapOptions = { center: new google.maps.LatLng(43.156608, -77.603989), zoom: 5, mapTypeId: google.maps.MapTypeId.ROADMAP };\n";

    js+="function initialize() {\n";
    js+="map = new google.maps.Map(document.getElementById(\"map_canvas\"), mapOptions);\n";
    js+="directionsService = new google.maps.DirectionsService();";
    
    for(int i=0; i<origin.length;i++){
    	js+="directionsDisplay"+i+" = new google.maps.DirectionsRenderer({\n";
    	js+="suppressMarkers: false,\n";
    	js+="suppressInfoWindows: true\n";
    	js+="});\n";
    	js+="directionsDisplay"+i+".setMap(map);\n";

    	js+="var request = {\n";
    	js+="origin: origin"+i+",\n"; 
    	js+="destination: destin"+i+",\n";
    	js+="travelMode: google.maps.DirectionsTravelMode.DRIVING\n";
    	js+="};\n";
    	js+="directionsService.route(request, function(response, status) {\n";
    	js+="if (status == google.maps.DirectionsStatus.OK) {\n";
    	js+="  directionsDisplay"+i+".setDirections(response);\n";
    	js+="}\n";
    	js+="});\n";



    }
      js+="}\n";
      js+="google.maps.event.addDomListener(window, 'load', initialize);\n";
	System.out.println(js);
}
public static void generatePopulationDistributionCoordinates(int n, String filename) throws IOException{
	FileWriter fstream = new FileWriter(filename);
	BufferedWriter out = new BufferedWriter(fstream);
	ArrayList<ArrayList<String>> populationDensities = CSVIO.readFile("population_densities_of_roc_tracts.csv");
	Map<String, ArrayList<String>> tractMap = readLocationsIntoTracts();
	Random rand = new Random();
	for (int i = 0; i < n; i++) {
		double densityPick = Double.parseDouble(getRandomValue(rand, 0, 1,
				7));

		int tractIndex = -1;
		// k>=1 because of header
		for (int k = populationDensities.size() - 1; k >= 1; k--) {
			if (densityPick < Double.parseDouble(populationDensities.get(k)
					.get(5))) {
				tractIndex = k;
			} else {
				break;
			}
		}
		if (tractIndex == -1) {
			System.err.println("Invalid distribution");
		}

		//System.out.println(tractIndex + ","	+ populationDensities.get(tractIndex).get(0));
		String tract11 = populationDensities.get(tractIndex).get(0);
		int numLocationsAvailableInTract = tractMap.get(tract11).size();
		if(numLocationsAvailableInTract>0){
			Random rand1 = new Random();
			int locIndex = rand1.nextInt(numLocationsAvailableInTract);
			
			//System.out.println(tractMap.get(tract11).get(locIndex));
			String[] latlng=tractMap.get(tract11).get(locIndex).split(",");
			String lat = latlng[0];
			String lng = latlng[1];
		    if(i%10==0)System.out.println(i+": "+tract11.substring(5)+", "+tract11+", "+ lat+", "+lng);
		    out.write(tract11.substring(5)+", "+tract11+", "+ lat+", "+lng+"\n");
		}

	}


	out.close();
}

public static Map<String,ArrayList<String>> readLocationsIntoTracts() throws IOException{
	Map<String,ArrayList<String>> tractMap = new HashMap<String,ArrayList<String>>();
	ArrayList<ArrayList<String>> locations = CSVIO.readFile("roc_20k_coordinates.csv");
	//ignore the header
	for(int i=1; i<locations.size();i++){
		String tract6 = locations.get(i).get(0);
		String tract11 = locations.get(i).get(1);
		String lat =locations.get(i).get(2);
		String lng = locations.get(i).get(3);
		
		if(!tractMap.containsKey(tract11)){
			tractMap.put(tract11, new ArrayList<String>());
		}
		tractMap.get(tract11).add(lat+","+lng);
		
	}
//	for(String key: tractMap.keySet()){
//		System.out.println(key + " : "+ tractMap.get(key).size());
//	}
	
	return tractMap;
	
}
}

